﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Objects;
using System.Data;
using Fujitsu.JiraAnalysis.Common;

namespace Fujitsu.JiraAnalysis.DAL
{
    public class VersionStorage
    {
        public IEventLog EventLog = new EventLogWrapper();

        public List<Version> GetProjectVersions(int projectId)
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                return (from v in db.Version
                        where v.ProjectID == projectId
                        select v).ToList();
            }
        }
        public int? AddVersion(Version dbVersion)
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                try
                {
                    db.AddToVersion(dbVersion);
                    db.SaveChanges();
                }
                catch (OptimisticConcurrencyException)
                {
                    db.Refresh(RefreshMode.ClientWins, dbVersion);
                    db.SaveChanges();
                }
                catch (DataException ex)
                {
                    EventLogger.CreateInstance(EventLog).LogWriteError(string.Concat("Can't add version to DB.", Environment.NewLine, ex.StackTrace));
                    return null;
                }

                return dbVersion.ID;
            }
        }

        public void UpdateVersion(Version dbVersion)
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                var versionToUpdate = db.Version.FirstOrDefault(i => i.ID == dbVersion.ID);

                if (versionToUpdate != null)
                {
                    versionToUpdate.ProjectID = dbVersion.ProjectID;
                    versionToUpdate.Name = dbVersion.Name;
                    versionToUpdate.Description = dbVersion.Description;
                    versionToUpdate.IsReleased = dbVersion.IsReleased;
                    versionToUpdate.IsArchived = dbVersion.IsArchived;
                    versionToUpdate.ReleaseDate = dbVersion.ReleaseDate;
                }

                db.SaveChanges();
            }
        }

        public Version GetVersion(int projectId, string jiraVersionId)
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                return db.Version.FirstOrDefault(i => i.ProjectID == projectId && i.JiraVersionID == jiraVersionId);
            }
        }

        public void DeleteVersion(int versionId)
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                var fixVersions = db.FixVersion.Where(f => f.VersionID == versionId);
                var fixVersionStorage = new FixVersionStorage();
                foreach (var fixVersion in fixVersions)
                {
                    fixVersionStorage.DeleteFixVersion(fixVersion.IssueID, fixVersion.VersionID);
                }
            }
            using (var db = new JiraAnalysisDBEntities())
            {
                var dbVersion = db.Version.FirstOrDefault(v => v.ID == versionId);
                if (dbVersion != null)
                {
                    try
                    {
                        db.Version.DeleteObject(dbVersion);
                        db.SaveChanges();
                    }
                    catch (OptimisticConcurrencyException)
                    {
                        db.Refresh(RefreshMode.ClientWins, dbVersion);
                        db.SaveChanges();
                    }
                    catch (DataException ex)
                    {
                        EventLogger.CreateInstance(EventLog).LogWriteError(string.Concat("Can't delete version from DB.", Environment.NewLine, ex.StackTrace));
                    }
                }
            }
        }

        public IEnumerable<int> GetVersionsToBeDeleted(int projectId, List<string> jiraVersionIds)
        {
            using (var db = new JiraAnalysisDBEntities())
            {
                return (from version in db.Version
                        where version.ProjectID == projectId && !jiraVersionIds.Any(v => v == version.JiraVersionID)
                        select version.ID).ToList();
            }
        }

        public void DeleteVersionsOfProject(int projectId)
        {
            var versions = GetProjectVersions(projectId);
            foreach (var version in versions)
            {
                DeleteVersion(version.ID);
            }
        }
    }
}
